﻿using ActiproSoftware.Windows.Shapes;
using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Aspose.Cells;
using CCTool.Scripts.Manager;
using CCTool.Scripts.ToolManagers.Extensions;
using CCTool.Scripts.ToolManagers.Managers;
using MathNet.Numerics.LinearAlgebra.Factorization;
using NPOI.OpenXmlFormats.Wordprocessing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace CCTool.Scripts.CusTool4
{
    /// <summary>
    /// Interaction logic for ExportBoundaryCom.xaml
    /// </summary>
    public partial class ExportBoundaryCom : ArcGIS.Desktop.Framework.Controls.ProWindow
    {
        string toolSet = "ExportBoundaryCom";
        public ExportBoundaryCom()
        {
            InitializeComponent();

            combox_xyDigit.Items.Add("1");
            combox_xyDigit.Items.Add("2");
            combox_xyDigit.Items.Add("3");
            combox_xyDigit.Items.Add("4");
            combox_xyDigit.Items.Add("5");
            combox_xyDigit.Items.Add("6");
            combox_xyDigit.SelectedIndex = 3;

            combox_mDigit.Items.Add("1");
            combox_mDigit.Items.Add("2");
            combox_mDigit.Items.Add("3");
            combox_mDigit.Items.Add("4");
            combox_mDigit.Items.Add("5");
            combox_mDigit.Items.Add("6");
            combox_mDigit.SelectedIndex = 1;

            // 读取参数
            textExcelPath.Text = BaseTool.ReadValueFromReg(toolSet, "excelPath");
            txt_js.Text = BaseTool.ReadValueFromReg(toolSet, "js");
            txt_sh.Text = BaseTool.ReadValueFromReg(toolSet, "sh");
            txt_time.Text = BaseTool.ReadValueFromReg(toolSet, "time");
        }

        // 定义一个进度框
        private ProcessWindow processwindow = null;
        string tool_name = "界址点导出Excel(A001)";


        private void combox_fc_DropDown(object sender, EventArgs e)
        {
            UITool.AddFeatureLayersToComboxPlus(combox_fc);
        }

        private void openExcelButton_Click(object sender, RoutedEventArgs e)
        {
            textExcelPath.Text = UITool.SaveDialogExcel();
        }

        private async void btn_go_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 参数获取
                string fc = combox_fc.ComboxText();
                string excelPath = textExcelPath.Text;

                string bzField = combox_bz.ComboxText();

                string js = txt_js.Text;
                string sh = txt_sh.Text;
                string time = txt_time.Text;

                int ptDigit = combox_xyDigit.Text.ToInt();
                int mDigit = combox_mDigit.Text.ToInt();

                // 记录参数
                BaseTool.WriteValueToReg(toolSet, "excelPath", excelPath);
                BaseTool.WriteValueToReg(toolSet, "js", js);
                BaseTool.WriteValueToReg(toolSet, "sh", sh);
                BaseTool.WriteValueToReg(toolSet, "time", time);

                // 判断参数是否选择完全
                if (fc == "" || bzField == "" || excelPath == "")
                {
                    MessageBox.Show("有必选参数为空！！！");
                    return;
                }

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                Close();

                await QueuedTask.Run(() =>
                {
                    // 获取目标FeatureLayer
                    FeatureLayer featurelayer = fc.TargetFeatureLayer();

                    // 复制界址点Excel表
                    DirTool.CopyResourceFile(@"CCTool.Data.Excel.杂七杂八.界址点成果表A001.xlsx", excelPath);
                    // 获取工作薄、工作表
                    string excelFile = ExcelTool.GetPath(excelPath);
                    int sheetIndex = ExcelTool.GetSheetIndex(excelPath);
                    // 打开工作薄
                    Workbook wb = ExcelTool.OpenWorkbook(excelFile);
                    // 打开工作表
                    Worksheet worksheet = wb.Worksheets[sheetIndex];
                    // 获取Cells
                    Cells cells = worksheet.Cells;

                    // 信息更新
                    cells["A74"].Value = $"计算者：{js}";
                    cells["C74"].Value = $"审核人：{sh}";
                    cells["E74"].Value = time;

                    // 设置分页信息
                    SetPage(featurelayer, cells);

                    int rowIndex = 3;   // 起始行
                    int pointIndex = 1;  // 起始点序号
                    int lastRowCount = 0;  // 上一轮的行数
                    int polygonCount = 0; // 环数


                    // 遍历面要素类中的所有要素
                    RowCursor cursor = featurelayer.Search();
                    while (cursor.MoveNext())
                    {
                        using var feature = cursor.Current as Feature;
                        // 获取要素的几何
                        Polygon geometry = feature.GetShape() as Polygon;

                        string bz = feature[bzField]?.ToString();   // BZ

                        if (geometry != null)
                        {
                            // 获取面要素的所有折点【按西北角起始，顺时针重排】
                            List<List<MapPoint>> mapPoints = geometry.ReshotMapPoint();

                            for (int i = 0; i < mapPoints.Count; i++)
                            {
                                // 输出折点的XY值和距离到Excel表
                                double prevX = double.NaN;
                                double prevY = double.NaN;

                                for (int j = 0; j < mapPoints[i].Count; j++)
                                {
                                    // 写入点号
                                    if (pointIndex - lastRowCount == mapPoints[i].Count)    // 找到当前环的最后一点
                                    {
                                        cells[rowIndex, 0].Value = $"J{lastRowCount - polygonCount + 1 - i}";

                                        polygonCount++;     // 环数加1
                                    }
                                    else
                                    {
                                        cells[rowIndex, 0].Value = $"J{pointIndex - polygonCount - i}";
                                    }

                                    // 写入备注
                                    cells[rowIndex, 4].Value = bz;
                                    cells[rowIndex+1, 4].Value = bz;

                                    double x = Math.Round(mapPoints[i][j].X, ptDigit);
                                    double y = Math.Round(mapPoints[i][j].Y, ptDigit);
                                    // 写入折点的XY值
                                    cells[rowIndex, 1].Value = y;
                                    cells[rowIndex, 2].Value = x;

                                    // 设置单元格为数字型，小数位数
                                    Aspose.Cells.Style style = cells[rowIndex, 2].GetStyle();
                                    style.Number = 4;   // 数字型
                                    // 小数位数
                                    style.Custom = ptDigit switch
                                    {
                                        1 => "0.0",
                                        2 => "0.00",
                                        3 => "0.000",
                                        4 => "0.0000",
                                        _ => null,
                                    };
                                    // 设置
                                    cells[rowIndex, 1].SetStyle(style);
                                    cells[rowIndex, 2].SetStyle(style);

                                    // 计算当前点与上一个点的距离
                                    if (!double.IsNaN(prevX) && !double.IsNaN(prevY) && rowIndex > 3)
                                    {
                                        string distance = Math.Sqrt(Math.Pow(x - prevX, 2) + Math.Pow(y - prevY, 2)).RoundWithFill(mDigit);
                                        // 写入距离【第一行不写入】
                                        cells[rowIndex - 1, 3].Value = distance;
                                        //if (j == mapPoints[i].Count - 1)
                                        //{
                                        //    cells[rowIndex - 1, 3].Value = "";
                                        //}
                                    }
                                    prevX = x;
                                    prevY = y;
                                    // 是否跨页
                                    if (rowIndex % 77 == 71)
                                    {
                                        rowIndex += 9;

                                        // 但是如果不是最后一个点，就回退
                                        if (pointIndex - lastRowCount != mapPoints[i].Count)
                                        {
                                            // 点号回退1
                                            j--;
                                            pointIndex--;
                                            // 距离归0
                                            prevX = double.NaN;
                                            prevY = double.NaN;
                                        }
                                    }
                                    else
                                    {
                                        rowIndex += 2;
                                    }
                                    pointIndex++;
                                }
                                lastRowCount += mapPoints[i].Count;
                            }
                        }

                    }

                    // 保存
                    wb.Save(excelPath);
                    wb.Dispose();

                    // 合并同值列
                    ExcelTool.MergeSameCol(excelPath, 4, 3);


                    pw.AddMessageEnd();
                });
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }


        private void combox_bz_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_bz);
        }

        private void btn_help_Click(object sender, RoutedEventArgs e)
        {
            string url = "https://blog.csdn.net/xcc34452366/article/details/149606062";
            UITool.Link2Web(url);
        }


        // 生成分页，并设置分页信息
        public static void SetPage(FeatureLayer featureLayer, Cells cells)
        {
            // 遍历面要素类中的所有要素
            RowCursor cursor = featureLayer.Search();

            long pointsCount = 0;

            while (cursor.MoveNext())
            {
                using var feature = cursor.Current as Feature;
                // 获取要素的几何
                Polygon polygon = feature.GetShape() as Polygon;

                // 获取面要素的所有折点【按西北角起始，顺时针重排】
                List<List<MapPoint>> mapPoints = polygon.ReshotMapPoint();
                // 计数
                foreach (var mapPoint in mapPoints)
                {
                    foreach (var point in mapPoint)
                    {
                        pointsCount++;
                    }
                }
            }

            // 计算要生成的页数
            long pageCount = (long)Math.Ceiling(((double)pointsCount) / 34);

            if (pageCount > 1)  // 多于1页
            {
                // 复制分页，前两页已有不用复制
                for (int i = 1; i < pageCount; i++)
                {
                    cells.CopyRows(cells, 0, i * 77, 77);
                }
            }

        }

    }
}
